package cn.tedu.tmall.front.mall.dao.repository.impl;

import cn.tedu.tmall.front.mall.dao.repository.ICartCacheRepository;
import cn.tedu.tmall.front.mall.pojo.po.CartPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Repository
public class CartCacheRepository implements ICartCacheRepository {

    private final String CART_KEY = "mall_cart_";

    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;

    @Override
    public void addCart(Long userId, CartPO cartPO) {
        log.debug("Repository-添加购物车-addCart: userId={}, cartPO={}", userId, cartPO);
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        Long hashKey = cartPO.getGoodsId();

        //todo 思考hash的value值存储什么，如何存取
        //方法1：取、改、存
//        CartPO oldCart = hashOperations.get(cartKey, goodsId);
//        if (oldCart != null){//购物车里已经有该商品
//            Integer oldCartQuantity = oldCart.getQuantity();
//            Integer newCartQuantity = cartPO.getQuantity();
//            cartPO.setQuantity(oldCartQuantity + newCartQuantity);
//        }
//        //添加新商品
//        hashOperations.put(cartKey, goodsId, cartPO);

        //方法2：想办法直接修改，不反复存取
        //把商品数量和是否选中单独拆出来
        String hashKeyQuantity = getHashKeyQuantity(hashKey);
        String hashKeyChecked = getHashKeyChecked(hashKey);
        String hashKeyGoods = getHashKeyGoods(hashKey);
        hashOperations.put(cartKey, hashKeyQuantity, cartPO.getGoodsNum());
        hashOperations.put(cartKey, hashKeyChecked, cartPO.getChecked());
        hashOperations.put(cartKey, hashKeyGoods, cartPO);
    }

    @Override
    public CartPO getGoodsByUserAndGoodsId(Long userId, Long goodsId) {
        HashOperations<String, String, CartPO> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String hashKeyGoods = getHashKeyGoods(goodsId);
        return hashOperations.get(cartKey, hashKeyGoods);
    }

    @Override
    public void modify(Long userId, Long goodsId, Integer goodsNum) {
        log.debug("Repository-购物车-修改数量-modify: userId={}, goodsId={}, quantity={}", userId, goodsId, goodsNum);
        HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String hashKeyQuantity = getHashKeyQuantity(goodsId);
        hashOperations.put(cartKey, hashKeyQuantity, goodsNum);
    }

    @Override
    public void increase(Long userId, Long goodsId, Integer goodsNum) {
        log.debug("Repository-购物车-增加数量-increase: userId={}, goodsId={}, quantity={}", userId, goodsId, goodsNum);
        HashOperations<String, String, CartPO> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String hashKeyQuantity = getHashKeyQuantity(goodsId);
        hashOperations.increment(cartKey, hashKeyQuantity, goodsNum);
    }

    @Override
    public List<CartPO> getCartList(Long userId) {
        HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        //1 通过大key全部查询,用程序来过滤
        Map<String, Object> entries = hashOperations.entries(cartKey);
        log.debug("Repository-购物车列表-全部查询-entries={}", entries);
        List<CartPO> cartPOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(entries)){
            entries.forEach((k, v) -> {
                if (k.contains(":goods")){
                    CartPO cartPO = (CartPO) v;
                    cartPOS.add(cartPO);
                }
                log.debug("Repository-购物车列表-筛选后的cartPO={}", v);
            });
            log.debug("Repository-购物车列表-筛选后的cartPOS={}", cartPOS);
        }
        cartPOS.forEach(cartPO -> {
            Long goodsId = cartPO.getGoodsId();
            String hashKeyQuantity = getHashKeyQuantity(goodsId);
            String hashKeyChecked = getHashKeyChecked(goodsId);
            Object goodsNum = entries.get(hashKeyQuantity);
            Object checked = entries.get(hashKeyChecked);
            cartPO.setGoodsNum((Integer) goodsNum);
            cartPO.setChecked((Integer) checked);
        });
        log.debug("Repository-购物车列表-更新了数据后返回的cartPOS={}", cartPOS);
        return cartPOS;
    }

    @Override
    public void delete(Long userId, Long goodsId) {
        log.debug("Repository-删除购物车-删除: userId={}, goodsId={}", userId, goodsId);
        HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String hashKeyQuantity = getHashKeyQuantity(goodsId);
        String hashKeyChecked = getHashKeyChecked(goodsId);
        String hashKeyGoods = getHashKeyGoods(goodsId);
        hashOperations.delete(cartKey, hashKeyQuantity);
        hashOperations.delete(cartKey, hashKeyChecked);
        hashOperations.delete(cartKey, hashKeyGoods);
    }

    @Override
    public void checked(Long userId, Long goodsId, Integer checked) {
        log.debug("Repository-购物车-选中/取消选中-checked: id={}, goodsId={}", userId, goodsId);
        HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String hashKeyChecked = getHashKeyChecked(goodsId);
        hashOperations.put(cartKey, hashKeyChecked, checked);
    }

    private String getCartKey(Long userId){
        return CART_KEY + userId;
    }

    private String getHashKeyQuantity(Long hashKey){
        return hashKey + ":quantity";
    }

    private String getHashKeyChecked(Long hashKey){
        return hashKey + ":checked";
    }

    private String getHashKeyGoods(Long hashKey){
        return hashKey + ":goods";
    }


}
